package com.xbongbong.paas.service.stage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xbongbong.paas.config.enums.WorkflowTriggerMethodEnum;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.RuleFieldRelationConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageTimeoutRemindEntity;
import com.xbongbong.paas.domain.entity.StageWorkflowEntity;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.StageSettingEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FilterConditionsPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.manager.feign.StageSyncFeignClient;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.StageTimeoutRemindModel;
import com.xbongbong.paas.model.StageWorkflowModel;
import com.xbongbong.paas.pojo.ExecutionEventFieldPojo;
import com.xbongbong.paas.pojo.ExecutionEventLinkDataPojo;
import com.xbongbong.paas.pojo.ExecutionEventPojo;
import com.xbongbong.paas.pojo.StageConditionLintAttrPojo;
import com.xbongbong.paas.pojo.StageConditionPojo;
import com.xbongbong.paas.pojo.StageLinkAttrPojo;
import com.xbongbong.paas.pojo.StageListPojo;
import com.xbongbong.paas.pojo.StageRemindPojo;
import com.xbongbong.paas.pojo.StageSavePojo;
import com.xbongbong.paas.pojo.StageWorkPojo;
import com.xbongbong.paas.pojo.StageWorkflowPojo;
import com.xbongbong.paas.pojo.dto.ExplainRelationListDTO;
import com.xbongbong.paas.pojo.dto.FormExplainListDTO;
import com.xbongbong.paas.pojo.dto.FormGetDTO;
import com.xbongbong.paas.pojo.dto.StageGetDTO;
import com.xbongbong.paas.pojo.dto.StageListDTO;
import com.xbongbong.paas.pojo.dto.StageSaveDTO;
import com.xbongbong.paas.pojo.dto.StageTitleFieldDTO;
import com.xbongbong.paas.pojo.dto.StageWorkGetDTO;
import com.xbongbong.paas.pojo.dto.StageWorkSaveDTO;
import com.xbongbong.paas.pojo.dto.StageWorkSortDTO;
import com.xbongbong.paas.pojo.dto.StageWorkflowListDTO;
import com.xbongbong.paas.pojo.dto.StartStageGetDTO;
import com.xbongbong.paas.pojo.vo.ExplainRelationListVO;
import com.xbongbong.paas.pojo.vo.FormSimpleListVO;
import com.xbongbong.paas.pojo.vo.LinkFormSimpleListVO;
import com.xbongbong.paas.pojo.vo.StageGetVO;
import com.xbongbong.paas.pojo.vo.StageLinkAttrVO;
import com.xbongbong.paas.pojo.vo.StageListVO;
import com.xbongbong.paas.pojo.vo.StageSaveVO;
import com.xbongbong.paas.pojo.vo.StageTitleFieldVO;
import com.xbongbong.paas.pojo.vo.StageWorkGetVO;
import com.xbongbong.paas.pojo.vo.StageWorkflowListVO;
import com.xbongbong.paas.service.stage.AbstractStageSettingsStrategy;
import com.xbongbong.paas.service.stage.StageHandle;
import com.xbongbong.paas.service.stage.StageHandleFactory;
import com.xbongbong.paas.service.stage.StageSettingService;
import com.xbongbong.paas.service.stage.StageSettingsFactory;
import com.xbongbong.paas.service.stage.StageSettingsStrategy;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.businesstage.pojo.SortPojo;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.ConditionLogicConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.StageConditionBusinessFieldEnum;
import com.xbongbong.pro.enums.StageConditionsFieldEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleConditionBusinessFieldEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleConditionFieldEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerStageErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.DelayTaskErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.form.pojo.RuleTargetPojo;
import com.xbongbong.pro.formexplain.pojo.FieldAndLogicPojo;
import com.xbongbong.pro.formexplain.pojo.LogicPojo;
import com.xbongbong.pro.formexplain.pojo.dto.FilterExplainByRuleDTO;
import com.xbongbong.pro.formexplain.pojo.vo.RuleFormExplainListVO;
import com.xbongbong.pro.opportunity.pojo.dto.OpportunityStageSyncDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.StageWorkEntity;
import com.xbongbong.saas.enums.ExecutionEventEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.help.StageHelp;
import com.xbongbong.saas.model.SaleStageModifyLogModel;
import com.xbongbong.saas.model.StageWorkModel;
import com.xbongbong.util.FilterExplainUtil;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.model.WorkflowModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 阶段设置
 * @author 李少杰
 * @version v1.0.0
 * @date 2021/11/26 13:44
 */
@Service("stageSettingService")
public class StageSettingServiceImpl implements StageSettingService {
    private static final Logger LOG = LoggerFactory.getLogger(StageSettingServiceImpl.class);
    @Resource
    private StageHandleFactory stageHandleFactory;
    @Resource
    private StageSettingsFactory stageSettingsFactory;
    @Resource
    private StageHelp stageHelp;
    @Resource
    private StageTimeoutRemindModel stageTimeoutRemindModel;
    @Resource
    private AbstractStageSettingsStrategy abstractStageSettingsStrategy;
    @Resource
    private StageWorkflowModel stageWorkflowModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private StageWorkModel stageWorkModel;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private StageSyncFeignClient stageSyncFeignClient;
    @Resource
    private SaleStageModifyLogModel saleStageModifyLogModel;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private ProBaseConfig proBaseConfig;


    @Override
    public StageGetVO get(StageGetDTO stageGetDTO) throws XbbException {

        String corpid = stageGetDTO.getCorpid();
        Long formId = stageGetDTO.getFormId();
        Long id = stageGetDTO.getId();
        Integer saasMark = stageGetDTO.getSaasMark();
        Integer businessType = stageGetDTO.getBusinessType();

        StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
        PaasStageEntity paasStageEntity = stageHandle.getByKey(id, corpid);
        if (Objects.isNull(paasStageEntity)) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238019);
        }
        List<StageWorkEntity> stageWorkEntityList = stageHelp.getStageWorkEntityByStage(corpid,formId, id);
        StageSettingsStrategy stageSettingsStrategy = stageSettingsFactory.getStageSettingsStrategy(paasStageEntity.getType());
        StageGetVO stageGetVO = stageSettingsStrategy.get(paasStageEntity, stageWorkEntityList);
        stageHandle.stageGetSettingAdvance(paasStageEntity, stageGetVO, StageSettingEnum.NEXT_STEP_STAGE_DETAIL.getCode());
        formatStagePreConditions(corpid, stageGetVO.getPreConditions());
        return stageGetVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StageSaveVO save(StageSaveDTO stageSaveDTO) throws XbbException {

        StageSaveVO stageSaveVO = new StageSaveVO();

        Long id = stageSaveDTO.getId();
        String corpid = stageSaveDTO.getCorpid();
        Long formId = stageSaveDTO.getFormId();
        Long stageProcessId = stageSaveDTO.getStageProcessId();
        Integer saasMark = stageSaveDTO.getSaasMark();
        Integer businessType = stageSaveDTO.getBusinessType();
        StageSavePojo stageSavePojo = stageSaveDTO.getStageSavePojo();
        stageSavePojo.setId(id);
        Integer type = stageSavePojo.getType();
        List<StageRemindPojo> stageRemindPojoList = stageSavePojo.getStageRemindPojoList();
        List<StageWorkflowPojo> stageWorkflowPojoList = stageSavePojo.getStageWorkflowPojoList();

        if (Objects.equals(stageSavePojo.getStayLimit(), 1)) {
            if (CollectionsUtil.isEmpty(stageRemindPojoList)) {
                // 如果选择【阶段停留xx小时后超时】则一定要设置【超时节点】
                throw new XbbException(DelayTaskErrorCodeEnum.API_ERROR_410002);
            }
            for (StageRemindPojo stageRemindPojo : stageRemindPojoList) {
                if (Objects.equals(stageRemindPojo.getRemindType(), BasicConstant.ONE)) {
                    long stayLimitTime = stageSavePojo.getStayLimitTime().longValue();
                    Integer stayLimitTimeUnit = stageSavePojo.getStayLimitTimeUnit();
                    Map<Integer, Integer> timeOutSetMap = new HashMap<>();
                    timeOutSetMap.put(1, TimeConstant.SECONDS_PER_HOUR);
                    timeOutSetMap.put(2, TimeConstant.SECONDS_PER_DAY);
                    timeOutSetMap.put(3, TimeConstant.SECONDS_PER_WEEK);
                    timeOutSetMap.put(4, TimeConstant.SECONDS_PER_MONTH);

                    //提前提醒时长
                    long advanceRemindTime = stageRemindPojo.getRemindTime() * TimeConstant.SECONDS_PER_HOUR;
                    //阶段停留时长
                    long stageStayTime = stayLimitTime * timeOutSetMap.get(stayLimitTimeUnit);
                    if (stageStayTime < advanceRemindTime) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.REMIND_TIME_MUST_BEYOND_INTO_TIME);
                    }
                }
            }
        }

        if (Objects.isNull(stageSavePojo.getEnableStageWarningColor())) {
            stageSavePojo.setEnableStageWarningColor(BasicConstant.ZERO);
        } else if (Objects.equals(stageSavePojo.getEnableStageWarningColor(), BasicConstant.ONE) && Objects.isNull(stageSavePojo.getStageWarningColor())) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238070);
        }


        PaasStageEntity oldPaasStageEntity;
        PaasStageEntity newPaasStageEntity;

        try {
            stageHelp.checkPaasAndNoUltimate(corpid, saasMark);
            if (Objects.isNull(id)) {
                throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238019);
            }
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            PaasStageEntity paasStageEntity = stageHandle.getByKey(id, corpid);
            if (Objects.isNull(paasStageEntity)) {
                throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238019);
            }
            StageSettingsStrategy stageSettingsStrategy = stageSettingsFactory.getStageSettingsStrategy(type);
            List<PaasStageEntity> stageEntityList = stageHelp.getStageEnableEntitys(corpid, saasMark, businessType, formId, stageProcessId);
            Map<Long, PaasStageEntity> paasStageEntityMap = stageEntityList.stream().collect(Collectors.toMap(PaasStageEntity::getId, t -> t, (t, t1) -> t1));
            PaasStageEntity saveStageEntity = stageHelp.wrapStageEntity(paasStageEntity, stageSavePojo);
            stageHandle.stageSaveSettingAdvance(saveStageEntity, stageSaveDTO.getStageSavePojo(), StageSettingEnum.NEXT_STEP_STAGE_DETAIL.getCode());
            oldPaasStageEntity = paasStageEntityMap.get(saveStageEntity.getId());
            paasStageEntityMap.put(saveStageEntity.getId(), saveStageEntity);
            Map<Integer, List<PaasStageEntity>> stageMap = abstractStageSettingsStrategy.getStageMap(new ArrayList<>(paasStageEntityMap.values()));
            List<PaasStageEntity> paasStageEntities = stageMap.get(type);
            abstractStageSettingsStrategy.stageNormalCheck(businessType, Collections.singletonList(saveStageEntity));
            stageSettingsStrategy.check(paasStageEntities, businessType);
            // 校验阶段任务
            List<StageWorkEntity> stageWorkEntityList = stageHelp.getStageWorkEntityByProcess(corpid, formId, paasStageEntity.getStageProcessId());
            Map<Long, List<StageWorkEntity>> stageWorkEntityMap = stageWorkEntityList.stream().collect(Collectors.groupingBy(StageWorkEntity::getStageId));
            for (PaasStageEntity stageEntity : paasStageEntities) {
                stageSettingsStrategy.checkStageWork(stageEntity, stageWorkEntityMap.get(stageEntity.getId()));
            }
            newPaasStageEntity = saveStageEntity;
            paasStageEntity.setUpdateTime(DateTimeUtil.getInt());
            saleStageModifyLogModel.saveModifyLogWhenUpdateStage(corpid, formId, stageProcessId, businessType, Lists.newArrayList(saveStageEntity));
            stageHandle.updateBatch(paasStageEntities, corpid);
            saveRemind(corpid, formId, stageProcessId, paasStageEntity.getId(), stageRemindPojoList);
            saveWorkflow(corpid, formId, stageProcessId, paasStageEntity.getId(), stageWorkflowPojoList);
            stageSaveVO.setId(paasStageEntity.getId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("StageSettingServiceImpl.save 保存阶段设置出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        //记录日志
        abstractStageSettingsStrategy.saveStageLog(stageSaveDTO, formId, Collections.singletonList(oldPaasStageEntity), Collections.singletonList(newPaasStageEntity));
        return stageSaveVO;
    }

    @Override
    public StageListVO list(StageListDTO stageListDTO) throws XbbException {

        StageListVO stageListVO = new StageListVO();
        String corpid = stageListDTO.getCorpid();
        Long id = stageListDTO.getId();
        Long formId = stageListDTO.getFormId();
        Integer saasMark = stageListDTO.getSaasMark();
        Integer businessType = stageListDTO.getBusinessType();

        try {
            stageHelp.checkPaasAndNoUltimate(corpid, saasMark);
            List<PaasStageEntity> stageEnableEntitys = stageHelp.getStageEnableEntitys(corpid, saasMark, businessType, formId, id);
            List<StageWorkEntity> stageWorkEntityList = stageHelp.getStageWorkEntityByProcess(corpid, formId, id);
            if (CollectionsUtil.isEmpty(stageEnableEntitys)) {
                throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238019);
            }
            Map<Long, List<StageWorkEntity>> stageWorkMap = new HashMap<>(stageEnableEntitys.size());
            stageEnableEntitys.forEach(item -> stageWorkMap.put(item.getId(), new ArrayList<>()));
            for (StageWorkEntity stageWorkEntity : stageWorkEntityList) {
                List<StageWorkEntity> workEntityList = stageWorkMap.get(stageWorkEntity.getStageId());
                if (Objects.nonNull(workEntityList)) {
                    workEntityList.add(stageWorkEntity);
                }
            }
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            List<StageListPojo> stageListPojo = stageHelp.getStageListPojo(stageEnableEntitys, stageWorkMap,stageHandle, StageSettingEnum.MAIN_CLICK_NEXT_STEP.getCode());
            stageListVO.setStageListPojoList(stageListPojo);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("查询阶段列表出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return stageListVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StageSaveVO stageWorkSave(StageWorkSaveDTO stageWorkSaveDTO) throws XbbException {
        StageSaveVO stageSaveVO = new StageSaveVO();
        Long id = stageWorkSaveDTO.getId();
        String corpid = stageWorkSaveDTO.getCorpid();
        Long formId = stageWorkSaveDTO.getFormId();
        Integer saasMark = stageWorkSaveDTO.getSaasMark();
        Integer businessType = stageWorkSaveDTO.getBusinessType();
        Long stageId = stageWorkSaveDTO.getStageId();
        StageWorkPojo stageWorkPojo = stageWorkSaveDTO.getStageWorkPojo();
        stageWorkPojo.setId(id);
        StageWorkEntity oldStageWorkEntity = null;
        StageWorkEntity stageWorkEntity;

        try {
            stageHelp.checkPaasAndNoUltimate(corpid, saasMark);
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            PaasStageEntity stageEntity = stageHandle.getByKey(stageId, corpid);
            if (Objects.isNull(stageEntity)) {
                throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238019);
            }
            List<StageWorkEntity> stageWorkEntityList = stageHelp.getStageWorkEntityByStage(corpid, formId, stageId);
            if (Objects.isNull(stageWorkEntityList)) {
                stageWorkEntityList = new ArrayList<>();
            }
            Integer stageBusinessType = stageHelp.getStageBusinessType(businessType);
            if (Objects.isNull(id)) {
                stageWorkEntity = new StageWorkEntity();
                stageWorkEntity.setCorpid(corpid);
                stageWorkEntity.setFormId(formId);
                stageWorkEntity.setStageProcessId(stageEntity.getStageProcessId());
                stageWorkEntity.setStageId(stageEntity.getId());
                stageWorkEntity.setStageCode(stageEntity.getCode());
                stageWorkEntity.setBusinessType(stageBusinessType);
                stageWorkEntity.setSaasMark(saasMark);
                stageWorkEntity.setAddTime(DateTimeUtil.getInt());
                stageWorkEntity.setIsEdit(true);
                stageHelp.wrapStageWorkEntity(stageWorkEntity, stageWorkPojo);

                stageWorkEntityList.add(stageWorkEntity);
                StageSettingsStrategy stageSettingsStrategy = stageSettingsFactory.getStageSettingsStrategy(stageEntity.getType());
                stageSettingsStrategy.checkStageWork(stageEntity, stageWorkEntityList);
                stageWorkModel.insert(stageWorkEntity);

                Map<Long, Integer> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                int count = stageWorkEntityList.size();
                for (StageWorkEntity sortStageWorkEntity : stageWorkEntityList) {
                    sortMap.put(sortStageWorkEntity.getId(), --count);
                }
                stageWorkModel.sort(corpid, formId, sortMap);
            } else {
                stageWorkEntity = stageWorkModel.getByKey(id, corpid);
                if (Objects.isNull(stageWorkEntity)) {
                    throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238020);
                }
                oldStageWorkEntity = new StageWorkEntity();
                BeanUtil.copyProperties(stageWorkEntity, oldStageWorkEntity);
                stageHelp.wrapStageWorkEntity(stageWorkEntity, stageWorkPojo);
                Map<Long, StageWorkEntity> stageWorkEntityMap = stageWorkEntityList.stream().collect(Collectors.toMap(StageWorkEntity::getId, Function.identity()));
                stageWorkEntity.setIsEdit(true);
                stageWorkEntityMap.put(stageWorkEntity.getId(), stageWorkEntity);
                abstractStageSettingsStrategy.checkStageWork(stageEntity, new ArrayList<>(stageWorkEntityMap.values()));
                saleStageModifyLogModel.saveModifyLogWhenUpdateStageWork(businessType, stageWorkEntity, oldStageWorkEntity);
                stageWorkModel.update(stageWorkEntity);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("阶段任务保存失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        // 记录日志
        if (Objects.nonNull(oldStageWorkEntity)) {
            abstractStageSettingsStrategy.saveStageWorkLog(stageWorkSaveDTO, formId, Collections.singletonList(oldStageWorkEntity), Collections.singletonList(stageWorkEntity));
        } else {
            abstractStageSettingsStrategy.saveStageWorkLog(stageWorkSaveDTO, formId, null, Collections.singletonList(stageWorkEntity));
        }

        stageSaveVO.setId(stageWorkEntity.getId());
        return stageSaveVO;
    }

    @Override
    public StageWorkGetVO stageWorkGet(StageWorkGetDTO stageWorkGetDTO) throws XbbException {
        StageWorkGetVO stageWorkGetVO = new StageWorkGetVO();
        String corpid = stageWorkGetDTO.getCorpid();
        Long formId = stageWorkGetDTO.getFormId();
        Integer saasMark = stageWorkGetDTO.getSaasMark();
        Integer businessType = stageWorkGetDTO.getBusinessType();
        Long id = stageWorkGetDTO.getId();

        stageHelp.checkPaasAndNoUltimate(corpid, saasMark);
        StageWorkEntity stageWorkEntity = stageWorkModel.getByKey(id, corpid);
        if (Objects.isNull(stageWorkEntity)) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238020);
        }

        StageWorkPojo stageWorkPojo = getStageWorkPojo(stageWorkEntity);
        wrapExecutionEventPojo(corpid, businessType, formId, stageWorkPojo.getExecutionEvent());
        stageWorkGetVO.setStageWorkPojo(stageWorkPojo);
        return stageWorkGetVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO stageWorkSort(StageWorkSortDTO stageWorkSortDTO) {

        String corpid = stageWorkSortDTO.getCorpid();
        Long formId = stageWorkSortDTO.getFormId();
        List<SortPojo> sortList = stageWorkSortDTO.getSortList();
        Map<Long, Integer> sortMap = sortList.stream().collect(Collectors.toMap(SortPojo::getId, SortPojo::getSort));
        stageWorkModel.sort(corpid, formId, sortMap);
        return new BaseVO();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StageSaveVO startSet(StageSaveDTO stageSaveDTO) throws XbbException {

        StageSaveVO stageSaveVO = new StageSaveVO();
        String corpid = stageSaveDTO.getCorpid();
        Long formId = stageSaveDTO.getFormId();
        Long stageProcessId = stageSaveDTO.getStageProcessId();
        Integer saasMark = stageSaveDTO.getSaasMark();
        Integer businessType = stageSaveDTO.getBusinessType();
        StageSavePojo stageSavePojo = stageSaveDTO.getStageSavePojo();

        try {
            stageHelp.checkPaasAndNoUltimate(corpid, saasMark);
            if (Objects.isNull(stageSavePojo.getOutProportion())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.STAGE_PROPORTION_NOT_NULL);
            }
            PaasStageEntity firstStageEntity = stageHelp.getFirstStageEntity(corpid, saasMark, businessType, formId, stageProcessId);
            firstStageEntity.setIntoProportion(stageSavePojo.getOutProportion());
            StageSettingsStrategy stageSettingsStrategy = stageSettingsFactory.getStageSettingsStrategy(StageTypeEnum.ORDINARY_STAGE.getType());
            List<PaasStageEntity> stageEntityList = stageHelp.getStageEnableEntitys(corpid, saasMark, businessType, formId, stageProcessId);
            Map<Long, PaasStageEntity> paasStageEntityMap = stageEntityList.stream().collect(Collectors.toMap(PaasStageEntity::getId, t -> t));
            paasStageEntityMap.put(firstStageEntity.getId(), firstStageEntity);
            Map<Integer, List<PaasStageEntity>> stageMap = abstractStageSettingsStrategy.getStageMap(new ArrayList<>(paasStageEntityMap.values()));
            List<PaasStageEntity> stageEntities = stageMap.get(StageTypeEnum.ORDINARY_STAGE.getType());
            stageSettingsStrategy.check(stageEntities, businessType);
            // 校验阶段任务
            List<StageWorkEntity> stageWorkEntityList = stageHelp.getStageWorkEntityByProcess(corpid, formId, firstStageEntity.getStageProcessId());
            Map<Long, List<StageWorkEntity>> stageWorkEntityMap = stageWorkEntityList.stream().collect(Collectors.groupingBy(StageWorkEntity::getStageId));
            for (PaasStageEntity stageEntity : stageEntities) {
                stageSettingsStrategy.checkStageWork(stageEntity, stageWorkEntityMap.get(stageEntity.getId()));
            }
            firstStageEntity.setUpdateTime(DateTimeUtil.getInt());
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            stageHandle.updateBatch(stageEntities, corpid);

            stageSaveVO.setId(firstStageEntity.getId());
            return stageSaveVO;
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("开始阶段设置出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public StageGetVO startGet(StartStageGetDTO startStageGetDTO) throws XbbException {

        String corpid = startStageGetDTO.getCorpid();
        Long formId = startStageGetDTO.getFormId();
        Integer saasMark = startStageGetDTO.getSaasMark();
        Integer businessType = startStageGetDTO.getBusinessType();
        Long stageProcessId = startStageGetDTO.getId();

        stageHelp.checkPaasAndNoUltimate(corpid, saasMark);
        PaasStageEntity firstStageEntity = stageHelp.getFirstStageEntity(corpid, saasMark, businessType, formId, stageProcessId);
        if (Objects.isNull(firstStageEntity)) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238019);
        }
        return abstractStageSettingsStrategy.wrapStageEntity(firstStageEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO stageWorkDel(StageWorkGetDTO stageWorkGetDTO) throws XbbException {
        String corpid = stageWorkGetDTO.getCorpid();
        Long id = stageWorkGetDTO.getId();

        StageWorkEntity stageWorkEntity = stageWorkModel.getByKey(id, corpid);
        if (Objects.isNull(stageWorkEntity) || Objects.equals(stageWorkEntity.getDel(), DelEnum.DELETE.getDel())) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238020);
        }

        saleStageModifyLogModel.saveModifyLogWhenDeleteStageWork(stageWorkGetDTO.getBusinessType(), stageWorkEntity);
        stageWorkModel.delete(stageWorkEntity);

        // 记录日志
        abstractStageSettingsStrategy.saveStageWorkLog(stageWorkGetDTO, stageWorkGetDTO.getFormId(), Collections.singletonList(stageWorkEntity), null);
        return new BaseVO();
    }

    @Override
    public StageTitleFieldVO getTitleField(StageTitleFieldDTO stageTitleFieldDTO) throws XbbException {
        StageTitleFieldVO stageTitleFieldVO = new StageTitleFieldVO();
        String corpid = stageTitleFieldDTO.getCorpid();
        Long formId = stageTitleFieldDTO.getFormId();
        Integer businessType = stageTitleFieldDTO.getBusinessType();
        try {
            if (Objects.isNull(businessType)) {
                businessType = XbbRefTypeEnum.PAAS.getCode();
            }
            PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, corpid);
            PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
            List<FieldAttrEntity> explainList = getExplainByTitle(explainEntity.getExplains());
            stageTitleFieldVO.setFormId(paasFormEntity.getId());
            stageTitleFieldVO.setFormName(paasFormEntity.getName());
            stageTitleFieldVO.setExplainList(explainList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("阶段设置-获取消息内容字段失败：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return stageTitleFieldVO;
    }

    @Override
    public StageLinkAttrVO getLinkAttr(StageTitleFieldDTO stageTitleFieldDTO) throws XbbException {
        StageLinkAttrVO stageLinkAttrVO = new StageLinkAttrVO();
        String corpid = stageTitleFieldDTO.getCorpid();
        Long formId = stageTitleFieldDTO.getFormId();
        Integer businessType = stageTitleFieldDTO.getBusinessType();
        try {
            if (Objects.isNull(businessType)) {
                businessType = XbbRefTypeEnum.PAAS.getCode();
            }
            PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
            List<FieldAttrEntity> explainList = JSON.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
            List<StageLinkAttrPojo> linkFieldAttrList = getLinkAttr(explainList, businessType, corpid);
            stageLinkAttrVO.setStageLinkAttrPojoList(linkFieldAttrList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("阶段设置-获取关联表单字段失败：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return stageLinkAttrVO;
    }

    @Override
    public LinkFormSimpleListVO getLinkFormList(FormGetDTO formGetDTO) throws XbbException {
        LinkFormSimpleListVO linkFormSimpleListVO = new LinkFormSimpleListVO();
        String corpid = formGetDTO.getCorpid();
        Integer businessType = formGetDTO.getBusinessType();
        Long formId = formGetDTO.getFormId();

        PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
        List<FieldAttrEntity> explainList = JSON.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        List<LinkInfoPojo> linkInfoPojoList = ProFormHelp.getLinkInfo(explainList);
        Map<Integer, List<LinkInfoPojo>> linkInfoPojoMap = linkInfoPojoList.stream().collect(Collectors.groupingBy(LinkInfoPojo::getLinkBusinessType));
        List<Long> linkFormList = linkInfoPojoList.stream().map(LinkInfoPojo::getLinkFormId).collect(Collectors.toList());
        List<LinkInfoPojo> workOrderLinkInfo = linkInfoPojoMap.get(XbbRefTypeEnum.WORK_ORDER.getCode());
        List<Long> workOrderFormList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(workOrderLinkInfo)) {
            workOrderFormList = workOrderLinkInfo.stream().map(LinkInfoPojo::getLinkFormId).collect(Collectors.toList());
        }
        List<PaasFormEntity> paasFormEntityList = proFormHelp.getPaasFormList(corpid, businessType, linkFormList);
        List<PaasFormEntity> workOrderFormEntityList = proFormHelp.getPaasFormList(corpid, XbbRefTypeEnum.WORK_ORDER.getCode(), workOrderFormList);
        paasFormEntityList.addAll(workOrderFormEntityList);
        if (CollectionsUtil.isNotEmpty(paasFormEntityList)) {
            List<PaasFormEntity> enablePaasFormEntities = paasFormEntityList.stream().filter(item -> Objects.nonNull(item.getEnable()) && Objects.equals(EnableEnum.OPEN.getCode(), item.getEnable())).collect(Collectors.toList());
            List<FormSimpleListVO> formSimpleListVOList = new ArrayList<>(enablePaasFormEntities.size());
            for (PaasFormEntity paasFormEntity : enablePaasFormEntities) {
                FormSimpleListVO formSimpleListVO = new FormSimpleListVO();
                formSimpleListVO.setFormId(paasFormEntity.getId());
                formSimpleListVO.setAppId(paasFormEntity.getAppId());
                formSimpleListVO.setBusinessType(paasFormEntity.getBusinessType());
                formSimpleListVO.setMenuId(paasFormEntity.getMenuId());
                formSimpleListVO.setName(paasFormEntity.getName());
                formSimpleListVO.setSaasMark(paasFormEntity.getSaasMark());
                formSimpleListVOList.add(formSimpleListVO);
            }
            linkFormSimpleListVO.setLinkformSimpleList(formSimpleListVOList);
        }
        return linkFormSimpleListVO;
    }

    @Override
    public BaseVO syncOpportunityData(OpportunityStageSyncDTO stageSyncDTO) throws XbbException {
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        XbbResponse<BaseVO> response = stageSyncFeignClient.stageSyncOpportunityData(stageSyncDTO, lang);
        if (!Objects.equals(response.getCode(), ErrorCodeEnum.API_SUCCESS.getCode())) {
            throw new XbbException(response.getCode(), response.getMsg());
        }
        return response.getResult();
    }

    @Override
    public RuleFormExplainListVO ruleList(FormExplainListDTO formExplainListDTO) throws XbbException {
        RuleFormExplainListVO formExplainListVO = new RuleFormExplainListVO();
        try {
            String corpid = formExplainListDTO.getCorpid();
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formExplainListDTO.getFormId(), formExplainListDTO.getBusinessType());

            if(Objects.nonNull(paasFormExplainEntity)) {
                Integer businessType = paasFormExplainEntity.getBusinessType();
                if (Objects.isNull(businessType)) {
                    // 工单的特殊处理
                    businessType = formExplainListDTO.getBusinessType();
                }
                // 加入当前数据字段
                List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
                FieldAndLogicPojo jsonObject = new FieldAndLogicPojo(FieldTypeEnum.DATAID.getAlias(), FieldTypeEnum.DATAID.getType(),  FieldTypeEnum.DATAID.getDescription(), 1, 0);
                LogicPojo equal = new LogicPojo(ConditionEnum.EQUAL.getMemo(), ConditionEnum.EQUAL.getSymbol());
                LogicPojo noEqual = new LogicPojo(ConditionEnum.NOEQUAL.getMemo(), ConditionEnum.NOEQUAL.getSymbol());
                List<LogicPojo> dataLogicList = new ArrayList<>(2);
                dataLogicList.add(equal);
                dataLogicList.add(noEqual);
                jsonObject.setValueTypeList(proFormHelp.getValueTypeList(FieldTypeEnum.DATAID.getType()));
                jsonObject.setLogicList(dataLogicList);
                conditionFieldList.add(jsonObject);

                List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                for (FieldAttrEntity fieldAttrEntity : fieldList) {
                    // 过滤掉非自定义字段和子表单
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    if (!Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldType)) {
                        // 过滤条件
                        FieldAndLogicPojo conditionField = getFieldAndLogic(fieldAttrEntity, businessType);
                        if (Objects.nonNull(conditionField)) {
                            conditionFieldList.add(conditionField);
                        }
                    }
                }
                formExplainListVO.setFormExplainList(conditionFieldList);
                formExplainListVO.setAppId(paasFormExplainEntity.getAppId());
                formExplainListVO.setFormExplainId(paasFormExplainEntity.getFormId());
                formExplainListVO.setFormId(paasFormExplainEntity.getFormId());
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("ruleList数据库搜索表单规则字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainListVO;
    }

    @Override
    public ExplainRelationListVO relationRuleList(ExplainRelationListDTO explainRelationListDTO) throws XbbException {
        ExplainRelationListVO explainRelationListVO = new ExplainRelationListVO();
        try {
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO();
            BeanUtil.copyProperties(explainRelationListDTO, filterExplainByRuleDTO);
            List<Integer> blockType = Collections.singletonList(FieldTypeEnum.DATETIME.getType());
            Integer fieldType = explainRelationListDTO.getFieldType();
            boolean block = blockType.contains(fieldType);
            List<FieldAttrEntity> jsonArray = getFieldListByRuleWithOutSubField(new RuleFieldRelationConstant(), filterExplainByRuleDTO, fieldType, block, true);
            formExplainHelp.addDataIdAsCondition(jsonArray, explainRelationListDTO.getFieldType(), filterExplainByRuleDTO, false);
            explainRelationListVO.setFormExplainList(jsonArray);
            explainRelationListVO.setAppId(explainRelationListDTO.getAppId());
            explainRelationListVO.setMenuId(explainRelationListDTO.getMenuId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("relationRuleList出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return explainRelationListVO;
    }

    @Override
    public StageTitleFieldVO getFieldConditions(StageTitleFieldDTO stageTitleFieldDTO) throws XbbException {
        StageTitleFieldVO stageTitleFieldVO = new StageTitleFieldVO();
        String corpid = stageTitleFieldDTO.getCorpid();
        Long formId = stageTitleFieldDTO.getFormId();
        Integer businessType = stageTitleFieldDTO.getBusinessType();
        Integer saasMark = stageTitleFieldDTO.getSaasMark();
        Integer fromType = stageTitleFieldDTO.getFromType();

        if (Objects.equals(saasMark, SaasMarkEnum.PAAS.getCode())) {
            businessType = XbbRefTypeEnum.PAAS.getCode();
        }
        PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
        List<FieldAttrEntity> explainList = getExplainByFieldConditions(businessType, explainEntity.getExplains(),fromType);
        stageTitleFieldVO.setExplainList(explainList);
        return stageTitleFieldVO;
    }

    @Override
    public StageWorkflowListVO workflowList(StageWorkflowListDTO stageWorkflowListDTO) throws XbbException {
        Map<String, Object> params = new HashMap<>();
        params.put(ParameterConstant.CORPID, stageWorkflowListDTO.getCorpid());
        params.put(ParameterConstant.APPID, stageWorkflowListDTO.getAppId());
        params.put(ParameterConstant.MENUID, stageWorkflowListDTO.getMenuId());
        params.put(ParameterConstant.FORMID, stageWorkflowListDTO.getFormId());
        params.put(ParameterConstant.DEL, 0);
        params.put("type", WorkflowTriggerMethodEnum.CUSTOM_TRIGGER_METHOD.getType());

        List<WorkflowEntity> workflowEntities = workflowModel.findEntitys(params);

        List<StageWorkflowListVO.WorkflowListPojo> workflowListPojos = workflowEntities.stream().map(v -> new StageWorkflowListVO.WorkflowListPojo(v.getId(), v.getName())).collect(Collectors.toList());

        StageWorkflowListVO stageWorkflowListVO = new StageWorkflowListVO();
        stageWorkflowListVO.setWorkflowList(workflowListPojos);
        return stageWorkflowListVO;
    }

    /**
     * 格式化阶段进入条件
     *  兼容老数据
     * @param corpid 公司id
     * @param stageConditionPojoList 阶段进入条件
     * @throws XbbException
     */
    private void formatStagePreConditions(String corpid, List<StageConditionPojo> stageConditionPojoList) throws XbbException {
        if (CollectionsUtil.isEmpty(stageConditionPojoList)) {
            return;
        }
        Set<Long> formIdSet = new HashSet<>();
        Set<Long> workOrderFormIdSet = new HashSet<>();
        for (StageConditionPojo stageConditionPojo : stageConditionPojoList) {
            StageConditionLintAttrPojo linkAttr = stageConditionPojo.getLinkAttr();
            if (Objects.isNull(linkAttr)) {
                continue;
            }
            if (Objects.equals(linkAttr.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                workOrderFormIdSet.add(linkAttr.getFormId());
            } else {
                formIdSet.add(linkAttr.getFormId());
            }
        }
        Map<Long, PaasFormExplainEntity> formExplainMap = null;
        Map<Long, Map<String, FieldAttrEntity>> workOrderFormFieldMap = null;
        if (CollectionsUtil.isNotEmpty(formIdSet)) {
            formExplainMap = proFormHelp.getFormExplainMap(formIdSet, corpid);
        }
        if (CollectionsUtil.isNotEmpty(workOrderFormIdSet)) {
            workOrderFormFieldMap = proFormHelp.getWorkOrderFormFieldMap(workOrderFormIdSet, corpid);
        }
        for (StageConditionPojo stageConditionPojo : stageConditionPojoList) {
            StageConditionLintAttrPojo linkAttr = stageConditionPojo.getLinkAttr();
            if (Objects.isNull(linkAttr)) {
                continue;
            }
            Long formId = linkAttr.getFormId();
            Integer businessType = linkAttr.getBusinessType();
            List<FilterConditionsPoJo> filter = stageConditionPojo.getFilter();
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode()) && Objects.nonNull(workOrderFormFieldMap)) {
                Map<String, FieldAttrEntity> stringFieldAttrEntityMap = workOrderFormFieldMap.get(formId);
                formatStageFilterConditions(stringFieldAttrEntityMap, filter);
            } else {
                if (Objects.nonNull(formExplainMap)) {
                    PaasFormExplainEntity paasFormExplainEntity = formExplainMap.get(formId);
                    if (Objects.isNull(paasFormExplainEntity)) {
                        continue;
                    }
                    Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                    formatStageFilterConditions(explainMap, filter);
                }
            }
        }

    }

    /**
     * 格式化进入条件字段条件
     * @param explainMap 解释
     * @param filter 字段条件
     */
    private void formatStageFilterConditions(Map<String, FieldAttrEntity> explainMap, List<FilterConditionsPoJo> filter) {
        if (Objects.isNull(explainMap) || CollectionsUtil.isEmpty(filter)) {
            return;
        }
        for (FilterConditionsPoJo filterConditionsPoJo : filter) {
            String attr = filterConditionsPoJo.getAttr();
            FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
            if (Objects.nonNull(fieldAttrEntity)) {
                filterConditionsPoJo.setAttrName(fieldAttrEntity.getAttrName());
                filterConditionsPoJo.setFieldType(fieldAttrEntity.getFieldType());
            }
        }
    }

    /**
     * 根据规则过滤字段且包含子字段
     * @param clazz 规则类
     * @param filterExplainByRuleDTO 查询字段列表的条件
     * @param fieldType 规则对应的字段
     * @param block 不可设置子表单的字段，如：日期，多选相关字段
     * @param condition 是否是条件，如果是操作的话，关联数据必须是表单id一致
     * @return 字段列表
     * @throws XbbException exception
     */
    public List<FieldAttrEntity> getFieldListByRuleWithOutSubField(Object clazz, FilterExplainByRuleDTO filterExplainByRuleDTO, Integer fieldType, boolean block, boolean condition) throws XbbException {
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        try {
            List<FieldAttrEntity> explainJsonArray;
            String corpid = filterExplainByRuleDTO.getCorpid();
            Long formId = filterExplainByRuleDTO.getFormId();
            Integer businessType = filterExplainByRuleDTO.getBusinessType();
            Integer saasMark = filterExplainByRuleDTO.getSaasMark();
            LinkInfoPojo linkInfoPojo = filterExplainByRuleDTO.getLinkInfo();
            Integer fieldBusinessType = filterExplainByRuleDTO.getLinkedType();
            Long linkFormId = null;
            if (Objects.nonNull(linkInfoPojo)) {
                fieldBusinessType = linkInfoPojo.getLinkBusinessType();
                linkFormId = linkInfoPojo.getLinkFormId();
                saasMark = linkInfoPojo.getLinkSaasMark();
            }
            boolean isDataId = Objects.equals(FieldTypeEnum.DATAID.getType(), fieldType);
            RuleTargetPojo ruleTargetPojo = filterExplainByRuleDTO.getTarget();
            if (isDataId && Objects.nonNull(ruleTargetPojo)) {
                fieldBusinessType = ruleTargetPojo.getLinkBusinessType();
                linkFormId = ruleTargetPojo.getFormId();
                saasMark = ruleTargetPojo.getLinkSaasMark();
            }
            PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
            if (Objects.isNull(explainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            explainJsonArray = JSON.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
            Set<Integer> fieldTypeSet = new HashSet<>();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (Objects.nonNull(fieldTypeEnum)) {
                String alias = fieldTypeEnum.getAlias().toUpperCase();
                if (ReflectHelper.exist(clazz, alias)) {
                    Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, alias);
                    fieldTypeSet.addAll(Arrays.asList(array));
                }
            }

            Map<Integer, List<String>> fieldBlockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fieldBlockMap.put(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(PaymentSheetEnum.PAY_METHOD.getAttr(), PaymentSheetEnum.FUND_ACCOUNT.getAttr()));
            for (FieldAttrEntity fieldAttrEntity : explainJsonArray) {
                if (fieldBlockMap.containsKey(businessType)) {
                    List<String> fieldBlockList = fieldBlockMap.get(businessType);
                    if (fieldBlockList.contains(fieldAttrEntity.getAttr())) {
                        continue;
                    }
                }
                Integer showType = fieldAttrEntity.getShowType();
                boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen()) || Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                    continue;
                }
                boolean  isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType());
                if (isLinkData) {
                    LinkInfoPojo linkInfoPojo1 = fieldAttrEntity.getLinkInfo();
                    businessType = linkInfoPojo1.getLinkBusinessType();
                    formId = linkInfoPojo1.getLinkFormId();
                }
                // TODO 过滤字段-暂时规则一致
                if (FilterExplainUtil.filterField(fieldAttrEntity, saasMark, businessType, fieldBusinessType, condition, formId, linkFormId, fieldType)) {
                    continue;
                }
                // 与业务规则的区别：去除子表单
                if (!Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldAttrEntity.getFieldType()) && fieldTypeSet.contains(fieldAttrEntity.getFieldType())) {
                    jsonArray.add(fieldAttrEntity);
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("根据规则过滤字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return jsonArray;
    }

    /**
     * 获取字段及逻辑运算符号
     * @param fieldAttrEntity 字段实体
     * @param businessType 业务类型
     * @return FieldAndLogicPojo 字段及逻辑运算封装
     * @throws XbbException exception
     */
    private FieldAndLogicPojo getFieldAndLogic(FieldAttrEntity fieldAttrEntity, Integer businessType) throws XbbException{
        // 开启、可见及业务规则可作条件字段
        boolean flag = Objects.equals(1, fieldAttrEntity.getIsOpen()) && Objects.equals(1, fieldAttrEntity.getVisible()) && Objects.nonNull(RuleConditionFieldEnum.getByCode(fieldAttrEntity.getFieldType()));
        // 系统字段
        JSONArray attrArray = RuleConditionBusinessFieldEnum.getAttrsByCode(businessType);
        boolean sysFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ZERO) && attrArray.contains(fieldAttrEntity.getAttr());
        // 自定义字段
        boolean cusFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ONE) && (Objects.isNull(fieldAttrEntity.getShowType()) || Objects.equals(0, fieldAttrEntity.getShowType()));

        if (flag && (sysFlag || cusFlag)) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum != null) {
                FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(fieldAttrEntity.getAttr(), fieldType, fieldAttrEntity.getAttrName(), fieldAttrEntity.getVisible(), fieldAttrEntity.getEditable());
                Object object = proFormHelp.getPrivateConst(fieldTypeEnum.getAlias(), ConditionLogicConstant.class);
                List<LogicPojo> logicList = proFormHelp.getLogicList(object, 0);
                // 设置值类型
                fieldAndLogicPojo.setValueTypeList(proFormHelp.getValueTypeList(fieldType));
                // 按照字段类型设置属性
                proFormHelp.setFieldAttr(fieldAttrEntity, fieldAndLogicPojo);
                fieldAndLogicPojo.setLogicList(logicList);
                return fieldAndLogicPojo;
            }
        }
        return null;
    }

    /**
     * 获取阶段消息内容支持的字段
     * @param explains 解释
     * @return 支持的字段列表
     */
    private List<FieldAttrEntity> getExplainByTitle(String explains) {
        List<FieldAttrEntity> explainList = JSON.parseArray(explains, FieldAttrEntity.class);
        // 单行文本、数字、下拉框、日期时间、单选按钮、成员单选、部门单选、创建人、创建时间、修改时间、拥有者、协同人、流水号、关联业务单选、关联业务多选
        List<Integer> titleFieldAttrList = Arrays.asList(1, 2, 4, 3, 10000, 10009, 10011, 10013, 10014, 10015, 10016, 10017, 10018, 10019, 10030, 20001, 20002);

        return explainList.stream().filter(item -> (Objects.isNull(item.getEditHide()) || Objects.equals(item.getEditHide(), EnableEnum.CLOSE.getCode())))
                .filter(item -> (Objects.isNull(item.getShowType()) || Objects.equals(item.getShowType(), ShowTypeEnum.ALL.getCode())))
                .filter(item -> (Objects.isNull(item.getIsOpen()) || Objects.equals(item.getIsOpen(), EnableEnum.OPEN.getCode())))
                .filter(item -> titleFieldAttrList.contains(item.getFieldType()))
                .collect(Collectors.toList());
    }

    /**
     * 获取字段条件中支持的字段
     * @param businessType 业务类型
     * @param explains 解释
     * @return 执行事件-字段筛选支持的字段
     */
    private List<FieldAttrEntity> getExplainByFieldConditions(Integer businessType, String explains,Integer fromType) {
        List<FieldAttrEntity> explainList = JSON.parseArray(explains, FieldAttrEntity.class);
        List<FieldAttrEntity> conditionsFieldList = new ArrayList<>();
        // 阶段推进器-字段筛选支持的系统字段
        JSONArray attrArray = StageConditionBusinessFieldEnum.getAttrsByCode(businessType);
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            boolean flag = Objects.equals(EnableEnum.OPEN.getCode(), fieldAttrEntity.getIsOpen()) && Objects.equals(EnableEnum.OPEN.getCode(), fieldAttrEntity.getVisible());
            boolean fieldTypeFlag = Objects.nonNull(StageConditionsFieldEnum.getByCode(fieldAttrEntity.getFieldType()));
            boolean sysFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ZERO) && attrArray.contains(fieldAttrEntity.getAttr());
            boolean specialFieldTypeFlag = specialBusinesstypeFieldType(businessType,attr,fromType);
            // 自定义字段
            boolean cusFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ONE) && (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.MANUAL_SIGN.getType()) || Objects.isNull(fieldAttrEntity.getShowType()) || Objects.equals(ShowTypeEnum.ALL.getCode(), fieldAttrEntity.getShowType()));
            if (flag && (fieldTypeFlag ||specialFieldTypeFlag) && (sysFlag || cusFlag)) {
                Integer fieldType = fieldAttrEntity.getFieldType();
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
                if (Objects.nonNull(fieldTypeEnum)) {
                   conditionsFieldList.add(fieldAttrEntity);
                }
            }
        }
        return conditionsFieldList;
    }

    /**
     * 特殊字段支持可选
     * date: 2022/8/30 9:46 上午
     * @author yingjf
     * @param businessType:
     * @param attr:
     */
    private boolean specialBusinesstypeFieldType(Integer businessType,String attr,Integer fromType){
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case SALES_OPPORTUNITY:
                if(Objects.equals(attr,SalesOpportunityEnum.WIN_COMPETITOR.getAttr()) && fromType!=null && Objects.equals(fromType,2)){
                    return true;
                }
                break;
            default:
                return false;
        }
        return false;
    }

    /**
     * 获取有关联数据的字段
     * @param explainList 字段解释
     * @return 阶段关联信息
     */
    public List<StageLinkAttrPojo> getLinkAttr(List<? extends FieldAttrEntity> explainList, Integer businessType, String corpid) {
        PaasFormEntityExt contactForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.CONTACT.getCode(), corpid);
        PaasFormEntityExt marketActivityForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.MARKET_ACTIVITY.getCode(), corpid);
        List<StageLinkAttrPojo> linkInfoList = new ArrayList<>();
        for (FieldAttrEntity item : explainList) {
            LinkInfoPojo linkInfoPojo = null;
            boolean isHaveLinkDataField = false;
            if (Objects.equals(item.getIsOpen(), 2)) {
                continue;
            }
            if ( Objects.equals(item.getIsRedundant(), BasicConstant.ONE)) {
                // 编辑关联数据支持关联数据单选，不支持关联数据多选，关联数据多选会有多条数据，相当于是批量编辑多条数据了
                if (Objects.equals(FieldTypeEnum.LINK_DATA.getType(), item.getFieldType())) {
                    isHaveLinkDataField = true;
                }
            } else if (Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()) && Objects.equals(item.getAttr(), SalesOpportunityEnum.CONTACT_NAME.getAttr())) {
                if (Objects.nonNull(contactForm)) {
                    //客户联系人
                    isHaveLinkDataField = true;
                    linkInfoPojo = new LinkInfoPojo(contactForm.getAppId(), contactForm.getId(), contactForm.getMenuId(), contactForm.getSaasMark(), contactForm.getBusinessType());
                }
            } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode()) && Objects.equals(item.getAttr(), ClueEnum.MARKET_ACTIVITY_ID.getAttr())) {
                if (Objects.nonNull(marketActivityForm)) {
                    //关联市场活动
                    isHaveLinkDataField = true;
                    linkInfoPojo = new LinkInfoPojo(marketActivityForm.getAppId(), marketActivityForm.getId(), marketActivityForm.getMenuId(), marketActivityForm.getSaasMark(), marketActivityForm.getBusinessType());
                }
            }
            if (isHaveLinkDataField) {
                StageLinkAttrPojo stageLinkAttrPojo = new StageLinkAttrPojo();
                stageLinkAttrPojo.setAttr(item.getAttr());
                stageLinkAttrPojo.setAttrName(item.getAttrName());
                stageLinkAttrPojo.setAttrNameEn(item.getAttrNameEn());
                stageLinkAttrPojo.setFieldType(item.getFieldType());
                stageLinkAttrPojo.setLinkInfo(Objects.isNull(linkInfoPojo) ? item.getLinkInfo() : linkInfoPojo);
                linkInfoList.add(stageLinkAttrPojo);
            }
        }
        return linkInfoList;
    }

    /**
     * 封装StageWorkPojo
     * @param stageWorkEntity 阶段实体
     * @return 阶段pojo
     */
    private StageWorkPojo getStageWorkPojo(StageWorkEntity stageWorkEntity) {
        StageWorkPojo stageWorkPojo = new StageWorkPojo();
        stageWorkPojo.setId(stageWorkEntity.getId());
        stageWorkPojo.setStageId(stageWorkEntity.getStageId());
        stageWorkPojo.setName(stageWorkEntity.getName());
        stageWorkPojo.setRequired(stageWorkEntity.getRequired());
        stageWorkPojo.setSort(stageWorkEntity.getSort());
        stageWorkPojo.setDescription(stageWorkEntity.getDescription());
        stageWorkPojo.setProportion(stageWorkEntity.getProportion());
        JSONArray executor = Objects.isNull(stageWorkEntity.getExecutor()) ? new JSONArray() : stageWorkEntity.getExecutor();
        stageWorkPojo.setExecutor(executor.toJavaList(OptionalRangeEntity.class));
        JSONObject executionEvent = Objects.isNull(stageWorkEntity.getExecutionEvent()) ? new JSONObject() :stageWorkEntity.getExecutionEvent();
        stageWorkPojo.setExecutionEvent(executionEvent.toJavaObject(ExecutionEventPojo.class));
        JSONArray completionCondition = Objects.isNull(stageWorkEntity.getCompletionCondition()) ? new JSONArray() : stageWorkEntity.getCompletionCondition();
        stageWorkPojo.setCompletionCondition(completionCondition.toJavaList(StageConditionPojo.class));
        return stageWorkPojo;
    }

    /**
     * 封装执行任务
     * @param corpid 公司id
     * @param businessType 业务类型
     * @param formId 表单id
     * @param executionEventPojo 执行事件pojo
     * @throws XbbException exception
     */
    private void wrapExecutionEventPojo(String corpid, Integer businessType, Long formId, ExecutionEventPojo executionEventPojo) throws XbbException {
        if (Objects.isNull(businessType) || Objects.isNull(formId)) {
            return;
        }
        if (Objects.isNull(executionEventPojo.getType())) {
            executionEventPojo.setType(ExecutionEventEnum.NULL.getType());
            return;
        }
        // 本表
        wrapExecutionEventFieldPojo(corpid, businessType, formId, executionEventPojo.getFieldList());
        ExecutionEventLinkDataPojo linkData = executionEventPojo.getLinkData();
        if (Objects.nonNull(linkData)) {
            // 关联表
            wrapExecutionEventFieldPojo(corpid, linkData.getBusinessType(), linkData.getFormId(), linkData.getFieldList());
        }
    }

    /**
     * 封装字段数据
     * @param corpid 公司id
     * @param businessType 业务类型
     * @param formId 表单id
     * @param executionEventFieldPojoList 执行事件字段列表
     * @throws XbbException exception
     */
    private void wrapExecutionEventFieldPojo(String corpid, Integer businessType, Long formId, List<ExecutionEventFieldPojo> executionEventFieldPojoList) throws XbbException {

        if (Objects.isNull(formId) || CollectionsUtil.isEmpty(executionEventFieldPojoList)) {
            return;
        }
        PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
        if (Objects.isNull(explainEntity)) {
            return;
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainEntity.getExplains());
        for (ExecutionEventFieldPojo executionEventFieldPojo : executionEventFieldPojoList) {
            FieldAttrEntity fieldAttrEntity = explainMap.get(executionEventFieldPojo.getAttr());
            if (Objects.isNull(fieldAttrEntity)) {
                continue;
            }
            executionEventFieldPojo.setAttrName(fieldAttrEntity.getAttrName());
            executionEventFieldPojo.setAttrNameEn(fieldAttrEntity.getAttrNameEn());
        }
    }

    /**
     * 保存超时设置
     * @param corpid 公司id
     * @param formId 表单id
     * @param stageProcessId 流程id
     * @param stageId 阶段id
     * @param stageRemindPojoList 阶段超时设置封装
     * @throws XbbException exception
     */
    private void saveRemind(String corpid, Long formId, Long stageProcessId, Long stageId, List<StageRemindPojo> stageRemindPojoList) throws XbbException {
        List<StageTimeoutRemindEntity> addRemindEntityList = new ArrayList<>();
        List<StageTimeoutRemindEntity> updateRemindEntityList = new ArrayList<>();

        try {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("formId", formId);
            param.put("stageProcessId", stageProcessId);
            param.put("stageId", stageId);
            param.put("del", 0);
            List<StageTimeoutRemindEntity> stageTimeoutRemindList = stageTimeoutRemindModel.findEntitys(param);
            List<Long> existRemindList = stageTimeoutRemindList.stream().map(StageTimeoutRemindEntity::getId).collect(Collectors.toList());

            if (CollectionsUtil.isNotEmpty(stageRemindPojoList)) {
                for (StageRemindPojo stageRemindPojo : stageRemindPojoList) {
                    StageTimeoutRemindEntity stageTimeoutRemindEntity = new StageTimeoutRemindEntity();
                    stageTimeoutRemindEntity.setId(stageRemindPojo.getId());
                    stageTimeoutRemindEntity.setCorpid(corpid);
                    stageTimeoutRemindEntity.setFormId(formId);
                    stageTimeoutRemindEntity.setStageProcessId(stageProcessId);
                    stageTimeoutRemindEntity.setStageId(stageId);
                    stageTimeoutRemindEntity.setRemindType(stageRemindPojo.getRemindType());
                    stageTimeoutRemindEntity.setRemindTime(stageRemindPojo.getRemindTime());
                    JSONArray remindUser = Objects.isNull(stageRemindPojo.getRemindUser()) ? new JSONArray() : JSONArray.parseArray(JSON.toJSONString(stageRemindPojo.getRemindUser()));
                    stageTimeoutRemindEntity.setRemindUser(remindUser);
                    JSONArray remindContent = Objects.isNull(stageRemindPojo.getRemindContent()) ? new JSONArray() : JSONArray.parseArray(JSON.toJSONString(stageRemindPojo.getRemindContent()));
                    stageTimeoutRemindEntity.setRemindContent(remindContent);
                    stageTimeoutRemindEntity.setDel(DelEnum.NORMAL.getDel());
                    stageTimeoutRemindEntity.setUpdateTime(DateTimeUtil.getInt());
                    if (Objects.isNull(stageRemindPojo.getId())) {
                        stageTimeoutRemindEntity.setAddTime(DateTimeUtil.getInt());
                        addRemindEntityList.add(stageTimeoutRemindEntity);
                        continue;
                    }
                    updateRemindEntityList.add(stageTimeoutRemindEntity);
                    existRemindList.remove(stageRemindPojo.getId());
                }
            }
            if (CollectionsUtil.isNotEmpty(addRemindEntityList)) {
                stageTimeoutRemindModel.insertBatch(addRemindEntityList);
            }
            if (CollectionsUtil.isNotEmpty(updateRemindEntityList)) {
                stageTimeoutRemindModel.updateBatch(updateRemindEntityList, corpid);
            }
            if (CollectionsUtil.isNotEmpty(existRemindList)) {
                stageTimeoutRemindModel.deleteByIdIn(corpid, existRemindList);
            }
        } catch (Exception e) {
            LOG.error("阶段超时设置保存失败 ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 保存自定义工作流
     * @param corpid 公司id
     * @param formId 表单id
     * @param stageProcessId 阶段流程id
     * @param stageId 阶段id
     * @param stageWorkflowPojoList 阶段工作流关联列表
     * @throws XbbException exception
     */
    private void saveWorkflow(String corpid, Long formId, Long stageProcessId, Long stageId, List<StageWorkflowPojo> stageWorkflowPojoList) throws XbbException {
        if (!packageHelp.isUltimateWithFeeType(corpid)) {
            // 非旗舰版直接返回
            LOG.error("not have workflow permission: " + corpid);
            return;
        }
        if (Objects.isNull(stageWorkflowPojoList)) {
            stageWorkflowPojoList = new ArrayList<>();
        }
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2 << 2);
        params.put(StringConstant.CORPID, corpid);
        params.put(StringConstant.FORM_ID, formId);
        params.put(ParameterConstant.STAGE_PROCESS_ID, stageProcessId);
        params.put(ParameterConstant.STAGE_ID, stageId);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<StageWorkflowEntity> stageWorkflowEntityList = stageWorkflowModel.findEntitys(params);
        Map<Long, StageWorkflowEntity> workflowEntityMap = stageWorkflowEntityList.stream().collect(Collectors.toMap(StageWorkflowEntity::getId, t -> t, (t, t1) -> t1));

        List<StageWorkflowEntity> addEntityList = new ArrayList<>();
        List<StageWorkflowEntity> updateEntityList = new ArrayList<>();
        List<String> repeatCheckList = new ArrayList<>(stageWorkflowPojoList.size());
        try {
            for (StageWorkflowPojo stageWorkflowPojo : stageWorkflowPojoList) {
                repeatCheckList.add(stageWorkflowPojo.getTriggerType() + "_" + stageWorkflowPojo.getRelatedStageId() + "_" + stageWorkflowPojo.getWorkflowId());
                StageWorkflowEntity stageWorkflowEntity = new StageWorkflowEntity();
                stageWorkflowEntity.setId(stageWorkflowPojo.getId());
                stageWorkflowEntity.setCorpid(corpid);
                stageWorkflowEntity.setFormId(formId);
                stageWorkflowEntity.setStageProcessId(stageProcessId);
                stageWorkflowEntity.setStageId(stageId);
                stageWorkflowEntity.setWorkflowId(stageWorkflowPojo.getWorkflowId());
                stageWorkflowEntity.setTriggerType(stageWorkflowPojo.getTriggerType());
                stageWorkflowEntity.setRelatedStageId(stageWorkflowPojo.getRelatedStageId());
                stageWorkflowEntity.setUpdateTime(DateTimeUtil.getInt());
                if (Objects.isNull(stageWorkflowPojo.getId())) {
                    stageWorkflowEntity.setAddTime(DateTimeUtil.getInt());
                    addEntityList.add(stageWorkflowEntity);
                    continue;
                }
                updateEntityList.add(stageWorkflowEntity);
                workflowEntityMap.remove(stageWorkflowEntity.getId());
            }

            if (CollectionsUtil.isNotEmpty(repeatCheckList)) {
                long count = repeatCheckList.stream().distinct().count();
                if (repeatCheckList.size() != count) {
                    throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238068);
                }
            }
            if (CollectionsUtil.isNotEmpty(addEntityList)) {
                stageWorkflowModel.insertBatch(addEntityList);
            }
            if (CollectionsUtil.isNotEmpty(updateEntityList)) {
                stageWorkflowModel.updateBatch(updateEntityList, corpid);
            }
            List<StageWorkflowEntity> deleteEntityList = new ArrayList<>(workflowEntityMap.values());
            if (CollectionsUtil.isNotEmpty(deleteEntityList)) {
                stageWorkflowModel.deleteBatch(deleteEntityList, corpid);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("阶段自定义工作流保存失败 ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

}
